package com.orange.common.ktx

import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.launch

/**
 *  参考
 *  https://juejin.cn/post/7001371050202103838#heading-7
 *  https://github.com/crazyqiang/AndroidStudy/blob/13b2f57666c4495ca361bfa2ecbf4a98dcdb3848/app/src/main/java/org/ninetripods/mq/study/kotlin/ktx/JetpackExt.kt
 */
/**
 * activity 内使用
 */
inline fun <T> Flow<T>.launchAndCollectIn(
    lifecycleOwner: LifecycleOwner,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
    crossinline block: suspend CoroutineScope.(T) -> Unit,
) = lifecycleOwner.lifecycleScope.launch {
    //前后台切换时可以重复订阅数据。如：Lifecycle.State是STARTED，那么在生命周期进入 STARTED 状态时开始任务，在 STOPED 状态时停止订阅
    flowWithLifecycle(lifecycleOwner.lifecycle, minActiveState).collect { block(it) }
}

/**
 * fragment 使用
 */
inline fun <T> Flow<T>.launchAndCollectIn(
    fragment: Fragment,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
    crossinline block: suspend CoroutineScope.(T) -> Unit,
) = fragment.viewLifecycleOwner.lifecycleScope.launch {
    //前后台切换时可以重复订阅数据。如：Lifecycle.State是STARTED，那么在生命周期进入 STARTED 状态时开始任务，在 STOPED 状态时停止订阅
    flowWithLifecycle(fragment.viewLifecycleOwner.lifecycle, minActiveState).collect { block(it) }
}

// inline fun <T> Flow<T>.launchAndSingleCollectIn(
//     lifecycleOwner: LifecycleOwner,
//     minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
//     crossinline block: suspend CoroutineScope.(T) -> Unit,
// ) = lifecycleOwner.lifecycleScope.launch {
//     flowOnSingleLifecycle(lifecycleOwner.lifecycle, minActiveState).collect { block(it) }
// }
//
// /**
//  * NOTE: 如果不想对UI层的Lifecycle.repeatOnLifecycle/Flow.flowWithLifecycle在前后台切换时重复订阅，可以使用此方法；
//  * 效果类似于Channel，不过Channel是一对一的，而这里是一对多的
//  */
// fun <T> Flow<T>.flowOnSingleLifecycle(
//     lifecycle: Lifecycle,
//     minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
//     isFirstCollect: Boolean = true,
// ): Flow<T> = callbackFlow {
//     var lastValue: T? = null
//     lifecycle.repeatOnLifecycle(minActiveState) {
//         this@flowOnSingleLifecycle.collect {
//             if ((lastValue != null || isFirstCollect) && (lastValue != it)) {
//                 send(it)
//             }
//             lastValue = it
//         }
//     }
//     lastValue = null
//     close()
// }
